package com.xframe.xdal.core.autofill;


import com.xframe.xdal.core.constant.RunOpportunity;
import com.xframe.xdal.core.exception.AutoProcRuntimeException;
import com.xframe.xdal.core.model.mapping.IColumnMapping;
import com.xframe.xdal.core.model.mapping.ITableInfo;
import com.xframe.xdal.core.util.CollectionUtil;
import com.xframe.xdal.core.util.StringUtil;
import com.xframe.xdal.core.util.XReflect;
import lombok.extern.log4j.Log4j2;

import java.util.Collection;


/**
 * 自动填充处理运行时
 *
 * @author xufeng
 * @date 2022-09-19
 * @version 1.0
 * */
@Log4j2
public class AutoProcRuntime {


    private AutoProcRuntime(){

    }

    private static AutoProcRuntime autoProcRuntime = new AutoProcRuntime();


    public static AutoProcRuntime getInstance(){
        return autoProcRuntime;
    }


    /**
     * 自动填充处理器工厂
     *
     * @param entity 被处理的对象
     * @param opportunity 当前处理的时机
     *
     * @return
     */
    public void autoFill(Object entity, ITableInfo tableInfo, RunOpportunity opportunity){
        try {
            if (entity == null) {
                return;
            }
            if (tableInfo == null) {
                return;
            }
            for (IColumnMapping columnMapping : tableInfo.getColumnMappingList()) {
                if (!CollectionUtil.isEmpty(columnMapping.getAutoFillBeanList())) {
                    for (IAutoFillBean autoFillBean : columnMapping.getAutoFillBeanList()) {
                        if (RunOpportunity.exists(autoFillBean.getOperateMark(), opportunity)) {
                            autoFillHelp(columnMapping.getFieldName(), columnMapping.getDataType(), entity, autoFillBean);
                        }
                    }
                }
            }
        }catch (Exception e){
            throw new AutoProcRuntimeException(e.getMessage());
        }
    }

    private void autoFillHelp(String fieldName,Class<?> fieldType,Object entity,IAutoFillBean autoFill){
        if (entity == null) {
            return;
        }
        if (fieldType == null) {
            return;
        }
        if (autoFill == null) {
            return;
        }
        if (StringUtil.isEmpty(fieldName)) {
            return;
        }
        Object fVal = XReflect.getFieldValue(entity,fieldName);
        if(autoFill.getOverwrite() || fVal == null || StringUtil.isEmpty(fVal.toString())) {
            IAutoProc autoProc = AutoFillFactory.create(autoFill, fieldType);
            Object val = autoProc.getVal(autoFill,entity,fVal);
            XReflect.setFieldValue(entity,fieldName,val);
        }
    }

    public void autoFill(Collection collection, ITableInfo tableInfo, RunOpportunity opportunity){
        if(collection == null){
            return;
        }
        if (tableInfo == null) {
            return;
        }
        Long startTime = System.currentTimeMillis();
        collection.forEach(obj -> autoFill(obj,tableInfo,opportunity));
        Long endTime = System.currentTimeMillis();
        log.info("{}ms",endTime - startTime > 0 ? endTime - startTime : 0L);
    }
}
